#include "mask.h"
#include <cmath>
#include <iostream>

Mask::Mask(){
    m = n = 3;
    w = new double*[m];
    for(int i = 0; i < m; i++){
        w[i] = new double[n];
    }

    for(int i = 0; i < m; i++){
        for(int j = 0; j < n; j++){
            w[i][j] = 1.0;
        }
    }
}

Mask::Mask(int _r, int _c) : m(_r), n(_c){
    w = new double*[m];
    for(int i = 0; i < m; i++){
        w[i] = new double[n];
    }

    for(int i = 0; i < m; i++){
        for(int j = 0; j < n; j++){
            w[i][j] = 1.0;
        }
    }
}

Mask::~Mask(){
	for(int i = 0; i < m; i++)
		delete[] w[i];
	delete[] w;
}

double Mask::getW(int _i, int _j){
    return w[getA() + _i][getB() + _j];
}

void Mask::setW(int _i, int _j, double _x){
    w[getA() + _i][getB() + _j] = _x;
}

int Mask::getM(){
    return m;
}

int Mask::getN(){
    return n;
}

int Mask::getA(){
    return floor(m/2);
}

int Mask::getB(){
    return floor(n/2);
}

void Mask::gaussian(double _sigma){
    int a = getA();
    int b = getB();
    double sigma_2 = _sigma * _sigma, i_2, j_2;
    for(int i = -a; i <= a; i++){
        for(int j = -b; j <= b; j++){
            i_2 = i*i;
            j_2 = j*j;
            w[i + a][j + b] = pow(M_E, -(i_2 + j_2)/(2*sigma_2));
        }
    }
}

void Mask::laplacian(int _neighborhood, int _negative){
    if (_negative == 0) _negative = -1;

    if(_neighborhood == 0){//vizinhança 4
        w[0][0] = w[2][2] = w[0][2] = w[2][0] = 0.0;
        w[1][0] = w[0][1] = w[1][2] = w[2][1] = -1 * _negative;
        w[1][1] = 4 * _negative;
    }else{
        w[0][0] = w[2][2] = w[0][2] = w[2][0] = -0.25 * _negative;
        w[1][0] = w[0][1] = w[1][2] = w[2][1] = -0.5 * _negative;
        w[1][1] = 3 * _negative;
    }
}

void Mask::weightedAverage(){
    int power;
    int a = getA();
    int b = getB();
    for(int i = -a; i <= a; i++){
        for(int j = -b; j <= b; j++){
            power = a + b - (fabs(i) + fabs(j));
            w[i + a][j + b] = pow(2, power);
        }
    }
}

void Mask::print(){
    std::cout << "Mascara " << m << " x " << n << std::endl;

    for(int i = 0; i < m; i++){
        for(int j = 0; j < n; j++){
            std::cout << w[i][j] << "\t";
        }
        std::cout << std::endl;
    }
}
